{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "64ccb33c-2450-4ffc-a0ed-7c1840489863",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "本机局域网IP: 192.168.101.8\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入要扫描的端口（多个用逗号分隔，例如 80,443,8080）:  5510\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "开始扫描 254 个IP的端口 [5510]...\n",
      "发现开放端口: 192.168.101.5:5510\n",
      "\n",
      "发现以下开放端口的设备:\n",
      "1. 192.168.101.5:5510\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "\n",
      "输入编号打开网页（直接回车退出）:  1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "正在打开: http://192.168.101.5:5510\n"
     ]
    }
   ],
   "source": [
    "import socket\n",
    "import ipaddress\n",
    "import concurrent.futures\n",
    "import re\n",
    "import platform\n",
    "import webbrowser\n",
    "\n",
    "def get_local_ip():\n",
    "    \"\"\"获取本机局域网IP地址\"\"\"\n",
    "    try:\n",
    "        # 创建一个UDP套接字（不会真正发送数据）\n",
    "        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:\n",
    "            s.connect((\"8.8.8.8\", 80))  # 连接到公共DNS服务器\n",
    "            local_ip = s.getsockname()[0]\n",
    "        return local_ip\n",
    "    except Exception:\n",
    "        return \"127.0.0.1\"  # 失败时返回回环地址\n",
    "\n",
    "def generate_ip_range(ip):\n",
    "    \"\"\"根据本机IP生成全网段IP列表\"\"\"\n",
    "    network = ipaddress.IPv4Network(ip + \"/24\", strict=False)\n",
    "    return [str(host) for host in network.hosts()]\n",
    "\n",
    "def scan_port(ip, port, timeout=2):\n",
    "    \"\"\"扫描指定IP和端口\"\"\"\n",
    "    try:\n",
    "        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:\n",
    "            s.settimeout(timeout)\n",
    "            result = s.connect_ex((ip, port))\n",
    "            if result == 0:\n",
    "                return (ip, port, True)\n",
    "    except Exception:\n",
    "        pass\n",
    "    return (ip, port, False)\n",
    "\n",
    "def main():\n",
    "    # 获取本机IP\n",
    "    local_ip = get_local_ip()\n",
    "    print(f\"本机局域网IP: {local_ip}\")\n",
    "    \n",
    "    # 生成扫描IP范围\n",
    "    ip_list = generate_ip_range(local_ip)\n",
    "    \n",
    "    # 输入需要扫描的端口\n",
    "    ports_input = input(\"请输入要扫描的端口（多个用逗号分隔，例如 80,443,8080）: \")\n",
    "    ports = [int(p.strip()) for p in ports_input.split(\",\")]\n",
    "    \n",
    "    print(f\"\\n开始扫描 {len(ip_list)} 个IP的端口 {ports}...\")\n",
    "    \n",
    "    found = []\n",
    "    \n",
    "    # 使用线程池加速扫描\n",
    "    with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:\n",
    "        futures = []\n",
    "        for ip in ip_list:\n",
    "            for port in ports:\n",
    "                futures.append(executor.submit(scan_port, ip, port))\n",
    "        \n",
    "        for future in concurrent.futures.as_completed(futures):\n",
    "            ip, port, status = future.result()\n",
    "            if status:\n",
    "                print(f\"发现开放端口: {ip}:{port}\")\n",
    "                found.append( (ip, port) )\n",
    "    \n",
    "    # 显示结果\n",
    "    if not found:\n",
    "        print(\"\\n未找到任何开放指定端口的设备\")\n",
    "        return\n",
    "    \n",
    "    print(\"\\n发现以下开放端口的设备:\")\n",
    "    for i, (ip, port) in enumerate(found, 1):\n",
    "        print(f\"{i}. {ip}:{port}\")\n",
    "    \n",
    "    # 询问是否打开浏览器\n",
    "    choice = input(\"\\n输入编号打开网页（直接回车退出）: \")\n",
    "    if choice.isdigit() and 0 < int(choice) <= len(found):\n",
    "        ip, port = found[int(choice)-1]\n",
    "        url = f\"http://{ip}:{port}\"\n",
    "        print(f\"正在打开: {url}\")\n",
    "        webbrowser.open(url)\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "217de12f-1694-457e-8075-53c8520efc62",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
